package org.zs.service.Impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.zs.dao.UserDaoTx;
import org.zs.service.UserServiceTs;

import javax.annotation.processing.FilerException;

//@Service
//@Transactional
//public class UserServiceTsImpl implements UserServiceTs {
//
//    @Autowired
//    private UserDaoTx userDaoTx;
//    @Override
//    public void updateUserInfo() {
//        int number = userDaoTx.updateNameById("wangwu", 3);
//        System.out.println("-----------" + number + "-------------");
//        System.out.println("------------------------");
//        int number1 = 1/0;
//        int index = userDaoTx.updateNickNameById("zhaoliu", 4);
//        System.out.println("-----------" + index + "-------------");
//    }
//}


@Service
@Transactional(readOnly = false, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class, noRollbackFor = FilerException.class, timeout = 3)
public class UserServiceTsImpl implements UserServiceTs {
    /*
    * 细节1： 注解的位置@Target({ElementType.TYPE, ElementType.METHOD})
    *       类上： 添加到类上，类下的所有方法都添加了事务（推荐）
    *       方法上：只有当前方法添加事务
    * 细节2： boolean readOnly() default false; 只读模式默认是非只读
    *        true： 事务中只能查询，不能修改 | 包含查询报错 Connection is read-only Queries leading to data modification are not allowed
    *        false: 可以组合查询，可以修改
    * 细节3： timeout = -1 事务永远不超时。 TransactionTimeOutException
    *        timeout = 3 3秒  超过3秒会抛出异常
    * 细节4: 事务的隔离级别  Isolation isolation() default Isolation.DEFAULT;
    *       mysql 第三个隔离级别  REPEATABLE_READ  可重复读
    * 细节5： 指定回滚异常和不回滚异常
    *       默认： @Transactional只有发生运行时异常才会回滚 RuntimeException
    *       为啥FileNotFoundException 不回滚？  不在指定的异常范围
    *       设置回滚异常：rollbackFor = Exception.class
    *       设置不回滚异常：noRollbackFor = FileNotFoundException.class
    *       注意：noRollbackFor指定的异常一定在rollbackFor范围内
    * 细节6：传播行为： Propagation propagation() default Propagation.REQUIRED;
    *       什么事传播行为： 最好是那种行为？？？
    *       指的多个业务方法调用，每个业务方法本身就是一个事务，事务的传播行为会决定被调用的业务的事务是否加入到腐父事务中
    *       推荐被调用的service加入到调用service的事务，最终形成一个事务！！！保证宏观角度的事务一致性
    *       是子业务方法添加传播行为属性决定！！！ Propagation propagation() default Propagation.REQUIRED;【加入到父事务中】
    *                      aservice
    *       controller        |              决定bservice是否加入到aservice的事务
    *                      bservice
    *
    *   Propagation.REQUIRED 必须的 子业务方法必须在事务中执行，父方法中有事务，加入到父方法的事务，如果没有，自己独自创建
    *   Propagation.SUPPORTS  父方法有事务，我就加入， 父方法没有事务， 我也没有事务执行
    *   Propagation.MANDATORY  父方法必须有事务。 有我正常加入 ，没有我抛异常
    *   Propagation.REQUIRES_NEW 不管父方法是否有事务，我们都是会使用独立的事务（3个事务）
    *  Propagation.NOT_SUPPORTED 不管父方法有没有事务，我都不会在事务中执行
    *  Propagation.NEVER  必须在无事务的环境下执行，父方法没有事务，咱们正常没事务执行。有事务了 我就抛异常
    *  Propagation.NESTED
    *
    *
    * */

    @Autowired
    private UserDaoTx userDaoTx;
    @Override
    public void updateUserInfo() {
        int number = userDaoTx.updateNameById("wangwu", 3);
        System.out.println("-----------" + number + "-------------");
        System.out.println("------------------------");
        int number1 = 1/0;
        int index = userDaoTx.updateNickNameById("zhaoliu", 4);
        System.out.println("-----------" + index + "-------------");
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void changeName() {
        int number = userDaoTx.updateNameById("wangwu", 3);
        System.out.println("changeName:" + number);
    }
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void changeName1() {
        int number = userDaoTx.updateNameById("wangwu", 3);
        System.out.println("changeName1:" + number);
    }

}
